package com.zyx.jdbcdemo.ck;


import com.zyx.jdbcdemo.utils.SqlUtil;
import lombok.extern.slf4j.Slf4j;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.time.Instant;
import java.util.List;

/**
 * @author Yaxi.Zhang
 * @since 2021/8/11 10:10
 * desc: ClickHouse的jdbc工具
 */
@Slf4j
public class ClickHouseUtil extends SqlUtil {

    /**
     * 获取Clickhouse的JDBC连接
     * @param runEnv 运行环境(开发/测试/生产)
     * @return Clickhouse的JDBC连接
     */
    private static Connection getClickhouseConnection(String runEnv) {
        return getConnection("bigdata-clickhouse-" + runEnv);
    }

    /**
     * 批量插入数据到Clickhouse
     *
     * @param tList 待插入数据的列表
     * @param sql 插入数据的预编译sql语句
     * @param runEnv 运行环境
     * @param insertBatch 批量插入数据的条数
     * @param <T> 插入数据的泛型
     */
    public static <T> void insertListToClickhouse(List<T> tList,
                                                  String sql,
                                                  String runEnv,
                                                  int insertBatch) {
        try (Connection conn = getClickhouseConnection(runEnv); PreparedStatement ps = conn.prepareStatement(sql)) {
            // 禁止自动提交
            conn.setAutoCommit(false);
            // 开始时间
            long start = Instant.now().toEpochMilli();
            int rowCount = 0;
            for (T tObj : tList) {
                setPreparedStatement(ps, tObj);
                ps.addBatch();
                // 批量导入
                if (++rowCount % insertBatch == 0) {
                    ps.executeBatch();
                    conn.commit();
                    log.info("++++++++++++++++++++ ClickHouse已经插入{}条数据", rowCount);
                }
            }
            // 遍历结束后导入最后一批数据
            ps.executeBatch();
            conn.commit();
            // 结束时间
            long end = Instant.now().toEpochMilli();
            log.info("++++++++++++++++++++ ClickHouse插入成功,一共插入数据{}条,耗时{}ms", rowCount, (end - start));
        } catch (Exception ex) {
            ex.printStackTrace();
            log.error("++++++++++++++++++++ ClickHouse插入失败");
        }
    }

}
